var _ = require('lodash'),
    Comment = require('./comment.model'),
    GamePost = require('../gamePost/gamePost.model'),
    im = require('immutable'),
    faker = require('faker'),
    moment = require('moment'),
    shortid = require('shortid'),
    util = require ('util'),
    _debug = require('debug');

const DEFAULT_PAGESIZE = 10,
    MIN_PAGESIZE = 5,
    MAX_PAGESIZE = 25;

const debug = _debug('app:server:API_of_Comments')


exports.createNewComment = function(req, res, next) {

    var commentToCreate = new Comment(req.body)

    var currentDatetime = new Date();
    var datetimeHyphened = moment(currentDatetime).format("YYYY-MM-DD-HH-mm-ss")
    
    var slug_part = shortid.generate()
    var full_slug_part = datetimeHyphened + ':' + slug_part

    if (commentToCreate._parent){

        debug("This new Comment has a parent Comment.")

        var parent_comment = Comment.findById(commentToCreate._parent, function (err, parent_comment) {
            if (err) {
                res.status(500).json(err)
            }else{
                debug("Find the parent for this comment. Writing slugs.")

                commentToCreate.slug = parent_comment.slug + '/' + slug_part
                commentToCreate.full_slug = parent_comment.full_slug + '/' + full_slug_part
                commentToCreate.save(function (err, createdCommentDoc) {
                    if (err) res.status(500).json(err)
                    GamePost.findByIdAndUpdate(
                        createdCommentDoc._post,
                        {$push: {"_comments": createdCommentDoc._id}},        
                        {safe: true, upsert: true, new : true},
                        function(err, updatedPost) {
                            if (err) res.status(500).json(err)
                            debug('New Comment Parent Post Updated.')
                        }
                    );
                    debug('New Comment saved successfully.(Has Parent Comment)')
                    res.status(200).json(createdCommentDoc)
                })          
            }
        })      

    } else {
        commentToCreate.slug = slug_part
        commentToCreate.full_slug = full_slug_part
        commentToCreate.save(function (err, createdCommentDoc) {
            if (err) res.status(500).json(err)
            GamePost.findByIdAndUpdate(
                createdCommentDoc._post,
                {$push: {"_comments": createdCommentDoc._id}},        
                {safe: true, upsert: true, new : true},
                function(err, updatedPost) {
                    if (err) res.status(500).json(err)
                    debug('New Comment Parent Post Updated.')
                }
            );
            debug('New Comment saved successfully.(No Parent Comment)')
            res.status(200).json(createdCommentDoc)        
        })
    }
};


exports.getCommentsByGamePost = function(req, res, next) {
    Comment.find({ _post : req.params.gamePostId}, function (err, doc) {
      if (err) return next(err);
    }).sort({ full_slug: -1 })
      .populate('_creator', '_id name email')
      .exec(function (err, comments) {
          if (err) res.status(500).json(err)
          console.log('The comments are %s', comments)
          res.status(200).json(comments)
        });   
};

exports.getCommentsByGamePostPaged = function(req, res) {
    // if(req.query.page && req.query.page < 1) return res.status(400).send('Invalid page');
    // Parse the page size that client pass in
    var pageSize = (req.query.pagesize && req.query.pagesize <= MAX_PAGESIZE && req.query.pagesize > MIN_PAGESIZE) ? req.query.pagesize : DEFAULT_PAGESIZE;
    debug("Page Number: " + req.query.page_number);
    debug("_post: " + req.query.post_id);
    var page = parseInt(req.query.page_number) || 0;
    if (page < 1) page = 1;

    Comment.count( { _post : req.query.post_id} , function(err, count) {
        if (err) res.status(500).json(err)
        var query;

        // Set the post_id
        query = Comment.find( { _post : req.query.post_id} );
        query
            .limit(pageSize)
            .sort('date')
            .skip((page-1) * pageSize || 0)//doesn't scale well, I'll worry about it later
            .exec(function(err, comments) {
                if (err) {
                    res.status(500).json(err)
                } else {
                    setTimeout(function() {
                        return res.status(200).json({
                                page: page,
                                pages: Math.ceil(count / pageSize),
                                items: comments,
                                numItems: count
                             });
                    },200);  // Mock Latency for 200 ms.
                }
            });
    });
};

exports.index = function(req, res) {
    // if(req.query.page && req.query.page < 1) return res.status(400).send('Invalid page');
    // Parse the page size that client pass in
    var pageSize = (req.query.pagesize && req.query.pagesize <= MAX_PAGESIZE && req.query.pagesize > MIN_PAGESIZE) ? req.query.pagesize : DEFAULT_PAGESIZE;
    var page = parseInt(req.query.page) || 0;
    if (page < 1) page = 1;

    Comment.count({}, function(err, count) {
        if (err) res.status(500).json(err)
        var query;
        query = Comment.find();
        query
            .limit(pageSize)
            .sort('date')
            .skip((page-1) * pageSize || 0)//doesn't scale well, I'll worry about it later
            .exec(function(err, comments) {
                if (err) res.status(500).json(err)
                setTimeout(function() {
                    return res.status(200).json({
                            page: page,
                            pages: Math.ceil(count / pageSize),
                            items: comments,
                            numItems: count
                         });
                },200);  // Mock Latency for 200 ms.
            });
    });
};



// To make fake Comments. Not used anymore.
exports.faker = function(req, res) {
    
    var fakeItems = im.Range(1,100)
      .map( () => { 
        return new Comment({ title: faker.name.findName() });
      });
    Comment.insertMany(fakeItems, function(error, docs) {

        if (error) {
            return res.status(400).json({
                error_info: error,
            });
        } else {
            console.info('%d items were successfully stored.', docs.length);
            return res.status(200).json({
                items: fakeItems,
            });
        }
    });
};


// Test
exports.test = function(req, res, next) {
    res.status(200).json(req.params.id) 
};
